package longshu.data.common;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * RetV 返回值封装，常用于业务层需要多个返回值, 也用于服务端与客户端的 json 数据通信
 * <pre>
 * 实例
 * 1：服务端
 *    RetV retV = service.justDoIt(paras);
 *    return retV;
 * 2：javascript 客户端 ajax 回调函数通常这么用：
 *    success: function(retV) {
 *       if(retV.isOk) {
 *           // success
 *           processData(retV.data);
 *           processData(retV.otherData);
 *       } else {
 *           // fail
 *           alert(retV.msg);
 *       }
 *    }
 * </pre>
 *
 * @author LongShu 2017/12/16
 */
public class RetV extends HashMap<String, Object> implements Serializable {
    private static final long serialVersionUID = 1L;

    private static final String STATUS_OK = "isOk";// 存成败key
    private static final String DATA = "data";// 默认的数据key
    private static final String MSG = "msg";// 信息key

    public RetV() {
        super(8);
    }

    public static RetV create() {
        return new RetV();
    }

    public static RetV create(String key, Object value) {
        return new RetV().set(key, value);
    }

    public static RetV ok() {
        return create().setOk(true);
    }

    public static RetV ok(Object data) {
        return ok().setData(data);
    }

    public static RetV ok(String key, Object value) {
        return create(key, value).setOk(true);
    }

    public static RetV fail() {
        return create().setOk(false);
    }

    public static RetV fail(String msg) {
        return create().setOk(false).setMsg(msg);
    }

    public static RetV fail(String key, Object value) {
        return fail().set(key, value);
    }

    /****************/

    /**
     * 是否成功
     */
    public boolean isOk() {
        Boolean isOk = (Boolean) get(STATUS_OK);
        return isOk != null && isOk;
    }

    public RetV setOk(boolean ok) {
        return set(STATUS_OK, ok);
    }

    /**
     * @param data 默认的数据,其他数据用 {@link #set} 扩展
     */
    public RetV setData(Object data) {
        return set(DATA, data);
    }

    /**
     * 获取默认的数据,其他数据用 getXXX
     */
    public <T> T getData() {
        return getAs(DATA);
    }

    /**
     * @return 成败信息
     */
    public String getMsg() {
        return getAs(MSG);
    }

    public RetV setMsg(String msg) {
        return set(MSG, msg);
    }

    public RetV set(String key, Object value) {
        super.put(key, value);
        return this;
    }

    public RetV set(Map<String, Object> map) {
        super.putAll(map);
        return this;
    }

    public RetV set(RetV retV) {
        super.putAll(retV);
        return this;
    }

    public RetV delete(String key) {
        super.remove(key);
        return this;
    }

    /****************/

    @SuppressWarnings("unchecked")
    public <T> T getAs(String key) {
        return (T) get(key);
    }

    public String getStr(String key) {
        return (String) get(key);
    }

    public Integer getInt(String key) {
        return (Integer) get(key);
    }

    public Long getLong(String key) {
        return (Long) get(key);
    }

    public Boolean getBoolean(String key) {
        return (Boolean) get(key);
    }

    /**
     * key 不存在，或者 key 存在但 value 为null
     */
    public boolean isNull(String key) {
        return super.get(key) == null;
    }

    /**
     * key 存在，并且 value 为 true，则返回 true
     */
    public boolean isTrue(String key) {
        Object value = super.get(key);
        return Boolean.TRUE.equals(value);
    }

    /**
     * key 存在，并且 value 为 false，则返回 true
     */
    public boolean isFalse(String key) {
        Object value = super.get(key);
        return Boolean.FALSE.equals(value);
    }

    @Override
    public boolean equals(Object ret) {
        return ret instanceof RetV && super.equals(ret);
    }

}
